import { Injectable } from '@nestjs/common';
// import { ConfigService } from '@nestjs/config';
import { Article } from './article.entity';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { PagingResponse } from 'src/constants/common.constants';
import { AppArticleDtoParams, AppArticleListDto } from './dto/list.dto';
import { AddPushArticleDto, TestAddArticleDto } from './dto/add.dto';
import { PinyinService } from '../ai/pinyin.service';
import { TtsService } from '../ai/tts.service';
import { TranslateService } from '../ai/translate.service';
import { splitTextByLineBreak } from 'src/utils/text.util';
import { wait } from 'src/utils/date.util';
import { AppGatherService } from '../gather/gather.service';
// import { PassThrough } from 'stream';
@Injectable()
export class AppArticleService {
  private access_token: string;
  private expires_in: number;
  private timestamp: number;

  constructor(
    @InjectRepository(Article)
    private readonly AppArticleRepository: Repository<Article>,

    private readonly pinyinService: PinyinService,
    private readonly ttsService: TtsService,
    private readonly translateService: TranslateService,
    private readonly appGatherService: AppGatherService,
  ) {}

  async findAll(params: AppArticleListDto): Promise<PagingResponse<Article>> {
    // console.log(
    //   this.configService.get('DATABASE_HOST'),
    //   this.configService.get('database.host'),
    //   await this.cacheManager.get('key'),
    //   await this.userRepository.findAndCount({
    //     where: {
    //       ...params.params,
    //     },
    //   }),
    // );
    const [items, total] = await this.AppArticleRepository.findAndCount({
      skip: (params.pageNum - 1) * params.pageSize, // skip the items for the previous pages
      take: params.pageSize,
      where: {
        ...params.params,
      },
      select: [
        'id',
        'name',
        'size',
        'enName',
        'pinyinName',
        'duration',
        'gatherId',
        'sortOrder',
        'updatedAt',
        'createdAt',
        'vipLevel',
        // 'content',
      ],
      order: {
        sortOrder: 'ASC',
      },
    });
    const { pageSize, pageNum } = params;
    return {
      records: items,
      total,
      pageSize,
      current: pageNum,
      pages: Math.ceil(total / pageSize),
    };
    // const [items] = await this.AppArticleRepository.findAndCount({});
    // return items;
    // return await this.userRepository
    //   .createQueryBuilder()
    //   .where({ deleted: 0 })
    //   .select(['user_name', 'email'])
    //   .getMany();
    //   .find();
  }

  async findList(params: AppArticleDtoParams): Promise<Array<Article>> {
    return await this.AppArticleRepository.find({
      where: {
        ...params,
      },
    });
  }

  async findOne(id: number) {
    return await this.AppArticleRepository.findOne({
      where: {
        id,
      },
    });
  }

  async testCreate(data: TestAddArticleDto): Promise<Article> {
    const pinyinName = this.pinyinService
      .transform(data.name)
      .map((item) => item[0])
      .join('');
    // const contentList = splitTextByPunctuationWithCount(data.content, 3);
    const contentList = splitTextByLineBreak(data.content);
    const contentObjList = [];
    return new Promise(async (resolve) => {
      this.translateService
        .translate([data.name])
        .then(async (strList) => {
          const enName = strList[0];
          for (const content of contentList) {
            // console.log('batch create article content', content);
            // 等待异步函数执行完成
            await wait(3000);
            contentObjList.push({
              content,
              enContent: (await this.translateService.translate([content]))[0],
              pinyin: this.pinyinService
                .transform(content)
                .map((item) => item[0]),
              audio: await this.ttsService.txt2audio(
                { tex: content, voiceName: 'zh-CN-XiaoxiaoNeural' },
                Math.random().toString(36).substr(2, 15),
              ),
            });
            if (contentObjList.length === contentList.length) {
              const article = this.AppArticleRepository.create({
                ...data,
                enName,
                content: JSON.stringify(contentObjList),
                pinyinName,
                size: contentObjList
                  .map((item) => item.audio.size)
                  .reduce((a, b) => a + b, 0),
                duration: contentObjList
                  .map((item) => item.audio.duration)
                  .reduce((a, b) => a + b, 0),
              });
              resolve(article);
            }
          }
        })
        .catch(() => {
          console.error('translate 401');
        });
    });
  }

  async testBatchCreate(data: TestAddArticleDto[], gatherId: number) {
    const list: Article[] = [];
    for (const element of data) {
      list.push(await this.testCreate(element));
    }
    await this.AppArticleRepository.save(list);
    console.log('batch create article success');
    this.appGatherService.updateArticleTotal(gatherId);
    return list;
  }

  async create(data: AddPushArticleDto) {
    const { gatherId, sortOrder, vipLevel } = data;
    const pinyinName = this.pinyinService
      .transform(data.name)
      .map((item) => item[0])
      .join('');
    const contentObjList = [];
    const contentList = splitTextByLineBreak(data.content);
    const enContentList = splitTextByLineBreak(data.enContent);
    return new Promise(async (resolve) => {
      this.translateService
        .translate([data.name])
        .then(async (strList) => {
          const enName = strList[0];
          for (let i = 0; i < contentList.length; i++) {
            const content = contentList[i];
            const enContent = enContentList[i];
            // console.log('batch create article content', content);
            // 等待异步函数执行完成
            await wait(500);
            contentObjList.push({
              content,
              enContent,
              pinyin: this.pinyinService
                .transform(content)
                .map((item) => item[0]),
              audio: await this.ttsService.txt2audio(
                { tex: content, voiceName: 'zh-CN-XiaoxiaoNeural' },
                Math.random().toString(36).substr(2, 15),
              ),
            });
          }
          const article = this.AppArticleRepository.create({
            name: data.name,
            gatherId,
            enName,
            content: JSON.stringify(contentObjList),
            pinyinName,
            size: contentObjList
              .map((item) => item.audio.size)
              .reduce((a, b) => a + b, 0),
            duration: contentObjList
              .map((item) => item.audio.duration)
              .reduce((a, b) => a + b, 0),
            sortOrder,
            vipLevel,
          });
          await this.AppArticleRepository.save(article);
          await this.appGatherService.updateArticleTotal(gatherId);
          console.log('create article success');
          resolve(article);
        })
        .catch((error) => {
          console.error('article create txt2audio error', error);
        });
    });
  }
}
